Support for Motorrad Routenplaner (Map&Guide) .bcr files.
- Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de
+ Copyright (C) 2005-2006 Olaf Klein, o.b.klein@t-online.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
*/
+/*
+ 2006/01/22: reader simplified with inifile library
+*/
#include "defs.h"
#include "garmin_tables.h"
#include <stdlib.h>
#include <math.h>
#include "cet_util.h"
+#include "inifile.h"
#define MYNAME "bcr"
#undef BCR_DEBUG
-#define SEC_UNKNOWN 0
-#define SEC_CLIENT 1
-#define SEC_ROUTE 2
-#define SEC_DESCR 3
-#define SEC_COORD 4
-
#define R_EARTH 6371000 /* radius of our big blue ball */
/*
but this seems to be used by Map&Guide when exporting to XML.
*/
-static FILE *fin, *fout;
+static FILE *fout;
static char *filename;
static int curr_rte_num, target_rte_num;
static double radius;
+static inifile_t *ini;
/* placeholders for options */
{0, 0, 0, 0, 0}
};
-void
+static void
bcr_init_radius(void)
{
if (radius_opt != NULL) /* preinitialize the earth radius */
{
- radius = atof(radius_opt);
- if (radius < 0)
- fatal(MYNAME ": Sorry, the radius should be greater than zero!\n");
+ radius = atof(radius_opt);
+ if (radius < 0)
+ fatal(MYNAME ": Sorry, the radius should be greater than zero!\n");
}
else
- radius = (double)R_EARTH;
+ radius = (double)R_EARTH;
if (global_opts.verbose_status > 0)
- printf(MYNAME ": We calculate with radius %f meters.\n", radius);
+ printf(MYNAME ": We calculate with radius %f meters.\n", radius);
}
static void
bcr_rd_init(const char *fname)
{
filename = xstrdup(fname);
- fin = xfopen(fname, "r", MYNAME);
+ ini = inifile_init(fname, MYNAME);
bcr_init_radius();
}
static void
bcr_rd_deinit(void)
{
- fclose(fin);
+ inifile_done(ini);
xfree(filename);
}
/* ------------------------------------------------------------*/
-char *
-bcr_next_char(const char *buff)
-{
- char *result = (char *)buff;
- while (*result > '\0' && *result <= ' ') result++; /* trim leading spaces */
- return result;
-}
-
-waypoint *
-bcr_find_waypt(const char *name, route_head *route) /* find a waypt by name, create new */
-{ /* if not found */
- waypoint *wpt;
- queue *elem, *tmp;
-
- QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp)
- {
- wpt = (waypoint *) elem;
- if (0 == strcmp(wpt->shortname, name))
- return wpt;
- }
- wpt = waypt_new();
- wpt->shortname = xstrdup(name);
-
- return wpt;
-}
-
-void
+static void
bcr_create_waypts_from_route(route_head *route)
{
waypoint *wpt;
}
}
-void
+static void
bcr_wgs84_to_mercator(const double lat, const double lon, int *north, int *east)
{
double N, E;
*lon = (double)east * (double)180 / (radius * M_PI);
}
-static int
-bcr_sort_route_by_index_cb(const void *a, const void *b)
-{
- const waypoint *wa = *(waypoint **)a;
- const waypoint *wb = *(waypoint **)b;
- return wa->centiseconds - wb->centiseconds;
-}
-
-route_head *
-bcr_sort_route_by_index(route_head *route)
-{
- route_head *result;
- queue *elem, *tmp;
- waypoint **list;
- waypoint *wpt;
- int i;
- int count = route->rte_waypt_ct;
-
- if (count == 0) return (route); /* nothing to do */
-
- result = route_head_alloc();
- result->rte_name = xstrdup(route->rte_name);
- route_add_head(result);
-
- list = (waypoint **) xcalloc(route->rte_waypt_ct, sizeof(*list));
- i = 0;
- QUEUE_FOR_EACH((queue *)&route->waypoint_list, elem, tmp)
- {
- wpt = (waypoint *)elem;
- list[i++] = wpt;
- }
- qsort(list, route->rte_waypt_ct, sizeof(*list), bcr_sort_route_by_index_cb);
- for (i=0; i<count; i++)
- {
- wpt = list[i];
- wpt->centiseconds = 0; /* reset our index container */
- route_add_wpt(result, waypt_dupe(wpt));
- route_del_wpt(route, wpt);
- }
-
- xfree(list);
- route_del_head(route);
-
- return result;
-}
-
/* ------------------------------------------------------------- */
static void
bcr_data_read(void)
{
- char buff[1024];
- char *src;
- int section = SEC_UNKNOWN;
- char *c, *cx, *ctemp;
int index;
- int mlat, mlon; /* mercator data */
- double xalt;
- int line, skip;
-
+ char *str;
route_head *route;
- waypoint *wpt;
route = route_head_alloc();
- route_add_head(route);
- line = skip = 0;
- src = NULL;
+ if ((str = inifile_readstr(ini, "client", "routename")))
+ route->rte_name = xstrdup(str);
+
+ route_add_head(route);
+
+ for (index = 1; index > 0; index ++) {
- while (NULL != fgets(buff, sizeof(buff), fin))
- {
- line++;
-
- c = buff; /* trim the end of the buffer */
- cx = c + strlen(c) - 1;
- while ((cx > c) && (*cx <= ' '))
- {
- *cx = '\0';
- cx--;
- }
- if (src != NULL) xfree(src);
-
- src = xstrdup(buff);
- /* !! buff is now free and can be used */
-
- c = bcr_next_char(src); /* skip spaces */
- if (*c == '\0') continue; /* skip empty lines */
-
- if (*c == '[') /* new section */
- {
- skip = 0;
+ char station[32];
+ char *str;
+ int mlat, mlon; /* mercator data */
+ double xalt;
+ waypoint *wpt;
- c = bcr_next_char(++c);
- cx = strchr(c, ']');
- if (cx == NULL) fatal(MYNAME ": error in file structure (\"]\" expected)!\n");
+ snprintf(station, sizeof(station), "STATION%d", index);
+ if (NULL == (str = inifile_readstr(ini, "coordinates", station))) break;
- *cx = '\0';
- if (strcmp(c, "CLIENT") == 0) section = SEC_CLIENT;
- else if (strcmp(c, "ROUTE") == 0) section = SEC_ROUTE;
- else if (strcmp(c, "DESCRIPTION") == 0) section = SEC_DESCR;
- else if (strcmp(c, "COORDINATES") == 0) section = SEC_COORD;
- else
- {
- printf(MYNAME ": unknown section \"%s\".\n", c);
- skip = 1;
- }
- continue;
- }
-
- if (skip != 0) continue;
-
- cx = strchr(c, '=');
- if (cx == NULL) continue;
-
- *cx++ = '\0'; /* delimit in key and data */
-
- if ((section == SEC_CLIENT) && (strcmp(c, "ROUTENAME") == 0))
- {
- route->rte_name = xstrdup(cx);
- }
- else
- {
- if (strncmp(c, "STATION", 7) != 0) continue;
- index = atoi(c+7);
-
- /* bcr_find_waypt(... creates new waypoint, if not in queue */
+ if (2 != sscanf(str, "%d,%d", &mlon, &mlat))
+ fatal(MYNAME ": structure error at %s (Coordinates)!\n", station);
+
+ wpt = waypt_new();
- switch(section)
+ wpt->shortname = xstrdup(station);
+ bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude);
+
+ if (NULL != (str = inifile_readstr(ini, "client", station)))
{
- case SEC_CLIENT:
- wpt = bcr_find_waypt(c, route);
- wpt->centiseconds = index;
- ctemp = strchr(cx, ',');
- if (ctemp != NULL) *ctemp = ' ';
- if (2 != sscanf(cx, "%s %lf", buff, &xalt))
- fatal(MYNAME ": structure error on line %d!\n(data: %s=%s)\n", line, c, cx);
-#if 0
- if (xalt != 999999999)
- wpt->altitude = xalt / 3.2808; /* convert feet to meters */
-#endif
- route_add_wpt(route, wpt);
+ char *cx;
+
+ cx = strchr(str, ',');
+ if (cx == NULL)
+ fatal(MYNAME ": structure error at %s (Client)!\n", station);
+ *cx++ = '\0';
- if (case_ignore_strcmp(buff, "standort") == 0)
+ xalt = atof(cx);
+ if (xalt != 999999999) {
+ wpt->altitude = xalt / 3.2808; /* convert feet to meters */
+ }
+
+ if (case_ignore_strcmp(str, "Standort") == 0)
wpt->icon_descr = mps_find_desc_from_icon_number(18, MAPSOURCE);
- else if (case_ignore_strcmp(buff, "Town") == 0)
+ else if (case_ignore_strcmp(str, "Town") == 0)
wpt->icon_descr = mps_find_desc_from_icon_number(69, MAPSOURCE);
else
- printf(MYNAME ": Unknown icon \"%s\" found. Please report.\n", buff);
- break;
-
- case SEC_DESCR:
- wpt = bcr_find_waypt(c, route);
- wpt->centiseconds = index;
-
- ctemp = strchr(cx, '@');
- if (ctemp != NULL)
- {
- *ctemp-- = '\0';
- if (*ctemp == ',') *ctemp = '\0';
- }
- wpt->description = xstrdup(cx);
- break;
-
- case SEC_COORD:
- wpt = bcr_find_waypt(c, route);
- wpt->centiseconds = index;
- if (2 != sscanf(cx, "%d,%d", &mlon, &mlat))
- fatal(MYNAME ": structure error on line %d!\n", line);
-
- bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude);
- case SEC_ROUTE:
- break;
+ warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str);
}
- }
+
+ if (NULL != (str = inifile_readstr(ini, "description", station)))
+ wpt->description = xstrdup(str);
+
+ route_add_wpt(route, wpt);
}
- if (src != NULL) xfree(src);
- src = NULL;
-
- route = bcr_sort_route_by_index(route);
bcr_create_waypts_from_route(route);
}